package com.gaga.common.utils;

import com.gaga.common.enums.PlayerType;
import lombok.extern.slf4j.Slf4j;
import net.beadsproject.beads.core.AudioContext;
import net.beadsproject.beads.core.Bead;
import net.beadsproject.beads.core.UGen;
import net.beadsproject.beads.core.io.JavaSoundAudioIO;
import net.beadsproject.beads.data.Sample;
import net.beadsproject.beads.ugens.BiquadFilter;
import net.beadsproject.beads.ugens.Gain;
import net.beadsproject.beads.ugens.SamplePlayer;
import net.beadsproject.beads.ugens.Static;

import javax.sound.sampled.Mixer;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author liujia
 * @version 1.0
 * @date 2025/3/30-15:32
 */
@Slf4j
public class AudioPlayerUtils2 {

    /**
     * 播放完成回调方法
     */
    private Runnable onPlaybackFinished;
    private AudioContext ac;
    private SamplePlayer player;

    private Gain masterGain;

    private List<BiquadFilter> filters = new ArrayList<>();

    private AtomicBoolean isCompleted = new AtomicBoolean(false);

    private volatile PlayerType playerType;

    // 8个频段的中心频率（与UI对应）
    public static final float[] FREQUENCIES = {
            115, 240, 455, 800, 2000, 4500, 9000
    };

    // 新增成员变量
    private boolean isPaused = false;
    private float currentSpeedFactor = 1.0f;
    private float currentVolumeFactor = 1.0f;
    private double pausePosition = 0;

    // 新增设备选择相关成员变量
    private JavaSoundAudioIO audioIO;

    /**
     * 添加完成回调方法
     */
    public void setOnPlaybackFinished(Runnable callback) {
        this.onPlaybackFinished = callback;
    }

    /**
     * 初始化音频设备（兼容变速）
     *
     * @param filePath
     * @param deviceName
     */
    public void init(String filePath, String deviceName, PlayerType playerType) {
        try {
            File file = new File(filePath);
            if (!file.exists()) {
                log.error("音频文件不存在: " + filePath);
                return;
            }
            stop();
            // 等待线程终止
            Thread.sleep(50);
            Mixer.Info targetMixerInfo = DeviceInfoUtils.getTargetAudioDevice(deviceName, true);
            if (targetMixerInfo == null) {
                throw new IllegalArgumentException("设备未找到: " + deviceName);
            }
            releaseResources(); // 释放资源
            resetState(); // 重置状态

            // 初始化音频设备选择
            audioIO = new JavaSoundAudioIO(512);
            audioIO.selectMixer(DeviceInfoUtils.getMixerIndex(deviceName));

            // 使用配置好的音频IO
            ac = new AudioContext(audioIO);

            // 加载音频并验证
            Sample sample = null;
            try {
                sample = new Sample(filePath);
                if (sample.getLength() <= 0) {
                    log.error("无效的音频文件或不支持的格式");
                }
            } catch (Exception e) {
                log.error("音频文件加载失败: " + e.getMessage());
            }

            player = new SamplePlayer(ac, sample);
            player.setLoopType(SamplePlayer.LoopType.NO_LOOP_FORWARDS);
            this.playerType = playerType;
            isCompleted.set(false);// 重置完成状态

            Sample finalSample = sample;
            player.setEndListener(new Bead() {
                private double previousPosition = 0;
                private int stableCount = 0;
                private boolean started = false;

                @Override
                protected void messageReceived(Bead message) {
                    if (player != null) {
                        double currentPosition = player.getPosition();

                        // 确保音频已经开始播放（位置大于0）
                        if (!started && currentPosition > 0) {
                            started = true;
                            log.error("音频播放已真正开始！文件路径: " + filePath);
                        }

                        // 只有在播放已开始的情况下才检测结束
                        if (started) {
                            // 检查位置是否接近文件结尾或者播放位置停止变化
                            boolean nearEnd = currentPosition >= finalSample.getLength() - 100;
                            boolean positionStable = Math.abs(currentPosition - previousPosition) < 0.01;

                            if (nearEnd || positionStable) {
                                stableCount++;
                            } else {
                                stableCount = 0;
                            }

                            // 位置稳定一段时间或达到文件末尾，才认为是播放完成
                            if ((stableCount > 3 || currentPosition >= finalSample.getLength()) && !isCompleted.get()) {
                                isCompleted.set(true);
                                log.error("音频播放完成！文件路径: " + filePath);
                                if (onPlaybackFinished != null) {
                                    onPlaybackFinished.run();
                                }
                            }

                            previousPosition = currentPosition;
                        }
                    }
                }
            });

            // 初始化8段滤波器
            createFilters();
            // 创建主音量控制
            masterGain = new Gain(ac, 2, 1.0f);

            // 构建音频链：播放器 -> 各滤波器并联 -> 主音量 -> 输出
            UGen lastNode = player;
            for (BiquadFilter filter : filters) {
                filter.addInput(lastNode);
                lastNode = filter;
            }
            masterGain.addInput(lastNode);
            ac.out.addInput(masterGain);

        } catch (Exception e) {
            log.error("初始化音频播放器失败: " + e.getMessage());
            e.printStackTrace();
            releaseResources(); // 发生错误时释放资源
        }
    }

    public PlayerType getPlayerType() {
        return playerType;
    }


    private void createFilters() {
        for (float freq : FREQUENCIES) {
            BiquadFilter filter = new BiquadFilter(ac, 2, BiquadFilter.Type.PEAKING_EQ);
            filter.setFrequency(freq)
                    .setQ(1.0f)    // Q值可根据需求调整
                    .setGain(0.0f); // 默认增益0dB
            filters.add(filter);
        }
    }

    // 添加获取样本长度的方法，用于日志和调试
    public double getSampleLength() {
        return player != null && player.getSample() != null ? player.getSample().getLength() : 0;
    }

    // 添加获取当前播放位置的方法，用于日志和调试
    public double getCurrentPosition() {
        return player != null ? player.getPosition() : 0;
    }

    // 判断是否正在播放
    public boolean isPlaying() {
        return ac != null && ac.isRunning() && !isCompleted.get();
    }

    // 设置指定频段的增益（bandIndex: 0-6）
    public void setBandGain(int bandIndex, float gainDb) {
        if (bandIndex >= 0 && bandIndex < filters.size()) {
            filters.get(bandIndex).setGain(gainDb);
        }
    }


    /**
     * 播放
     */
    public void play() {
        if (ac == null || player == null) {
            log.error("播放器未正确初始化");
            return;
        }

        try {
            if (isPaused) {
                // 恢复播放：从暂停位置继续
//                setSpeed(currentSpeedFactor);
//                setVolume(currentVolumeFactor);
                player.setPosition(pausePosition);
                isPaused = false;
            } else {
                // 全新播放
                player.setPosition(0);
                isCompleted.set(false); // 确保重置播放完成状态
//                setSpeed(currentSpeedFactor);
//                setVolume(currentVolumeFactor);
                log.error("准备开始播放音频，已重置播放状态");
            }

            if (!ac.isRunning()) {
                // 这里添加延迟，确保音频引擎正确初始化
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                ac.start();
                log.error("音频引擎已启动");
            }

        } catch (Exception e) {
            log.error("播放音频时发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }


    /**
     * 停止
     */
    public void stop() {
        if (ac != null) {
            // 标记播放完成
            isCompleted.set(true);

            // 停止音频上下文
            if (ac.isRunning()) {
                ac.stop();
            }
            // 释放资源
            releaseResources();

            // 重置状态
            resetState();
        }
    }

    /**
     * 释放音频资源
     */
    private void releaseResources() {
        try {
            if (player != null) {
                Sample sample = player.getSample();
                if (sample != null) {
                    clearSampleData(sample); // 新增方法：清空音频数据
                }
                player.setEndListener(null);
                player.clearInputConnections();
                player.clearDependents();
                player = null;
            }

            // 2. 清理SampleManager静态集合（新增关键逻辑）
            clearSampleManagerStaticData();

            if (masterGain != null) {
                masterGain.clearInputConnections();
                masterGain = null;
            }

            if (filters != null) {
                for (BiquadFilter filter : filters) {
                    filter.clearInputConnections();
                }
                filters.clear();
            }

            if (ac != null) {
                ac.out.clearInputConnections();
                // 强制关闭所有线程
                ac.stop();

                // 添加额外的资源清理
                try {
                    Thread.sleep(50); // 等待短暂时间确保线程完全停止
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }

                ac = null;
            }

            if (audioIO != null) {
                // 使用反射强制终止音频线程
                try {
                    java.lang.reflect.Field threadField = JavaSoundAudioIO.class.getDeclaredField("audioThread");
                    threadField.setAccessible(true);
                    Thread audioThread = (Thread) threadField.get(audioIO);
                    if (audioThread != null && audioThread.isAlive()) {
                        audioThread.interrupt();

                        // 等待线程终止
                        try {
                            audioThread.join(100); // 最多等待100ms
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                        }
                    }
                } catch (Exception e) {
                    log.error("终止音频线程失败: " + e.getMessage());
                }

                audioIO = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 新增方法：通过反射清空Sample数据
    private void clearSampleData(Sample sample) {
        try {
            Field dataField = Sample.class.getDeclaredField("theSampleData");
            dataField.setAccessible(true);
            dataField.set(sample, null); // 清空float[][]数组
            log.info("已强制释放Sample音频数据");

        } catch (Exception e) {
            log.warn("清空Sample数据失败: {}", e.getMessage());
        }
    }

    /**
     * 通过反射清理SampleManager的静态集合
     */
    private void clearSampleManagerStaticData() {
        try {
            // 获取SampleManager的Class对象
            Class<?> sampleManagerClass = Class.forName("net.beadsproject.beads.data.SampleManager");

            // 清理samples集合（存储所有Sample实例）
            Field samplesField = sampleManagerClass.getDeclaredField("samples");
            samplesField.setAccessible(true);
            Map<String, Sample> samples = (Map<String, Sample>) samplesField.get(null);
            for (Sample sample : samples.values()) {
                clearSampleData(sample); // 清空每个Sample的音频数据
            }
            samples.clear(); // 移除所有引用

            // 清理groups集合（按组分组的Sample）
            Field groupsField = sampleManagerClass.getDeclaredField("groups");
            groupsField.setAccessible(true);
            Map<String, ArrayList<Sample>> groups = (Map<String, ArrayList<Sample>>) groupsField.get(null);
            for (List<Sample> group : groups.values()) {
                group.clear(); // 清空分组内的Sample引用
            }
            groups.clear();

            log.info("已清理SampleManager静态资源");
        } catch (Exception e) {
            log.error("清理SampleManager失败: {}", e.getMessage());
        }
    }

    private void resetState() {
        isCompleted.set(false);
        isPaused = false;
        pausePosition = 0;
        currentSpeedFactor = 1.0f;
        currentVolumeFactor = 1.0f;
        if (filters != null) {
            filters.clear();
        }
    }

    /**
     * 暂停播放（保留播放位置）
     */
    public void pause() {
        if (player != null && ac != null && ac.isRunning()) {
            // 记录当前播放位置和速度
            pausePosition = player.getPosition();
            currentSpeedFactor = player.getRateUGen().getValue();
            currentVolumeFactor = masterGain.getGain();
            // 设置速率为0实现暂停
            setSpeed(0f);
            setVolume(0f);
            isPaused = true;
        }
    }

    /**
     * 设置音量
     */
    public void setVolume(float volume) {
        masterGain.setGain(volume);
    }

    public void setSpeed(float factor) {
        UGen rateuGen = new Static(ac, Math.max(0.5f, Math.min(2.0f, factor)));
        player.setRate(rateuGen);
    }

    public static void main(String[] args) throws Exception {

        AudioPlayerUtils2 player = new AudioPlayerUtils2();
        //"C:/Users/lenovo/Desktop/test/1.mp3"
        player.init("C:\\Users\\Lenovo\\Desktop\\tmp\\1.wav", "1扬声器", PlayerType.ANCHOR);
        // 播放 这个播放速度需要修改
        player.setBandGain(3, 1f);
        player.setSpeed(1f);
        player.setVolume(1f);
        player.play();

        Thread.sleep(2000);
        player.setBandGain(3, 12f);


//        player.setVolume(0.2f);

//        player.pause();
//        Thread.sleep(9000);
//        player.play();

        Thread.sleep(10000);
        player.stop();

//        double audioDuration = DeviceInfoUtils.getAudioDuration("C:/Users/lenovo/Desktop/test/1.mp3");
//        System.out.println("音频时长：" + audioDuration + " 秒");

    }

}
